// *************************************
// * Creator:SunnyPaine
// * DateTime:2024/09/04 14:09:55
// * Description:<Description>
// * CopyRight:
// * ***********************************

using Autofac;
using SunnyPaine.Autofac.Extension.Mvvm.ViewCore;
using SunnyPaine.Autofac.Extension.Stereotype.Selector;
using SunnyPaine.SqlSugar.Autofac.Stereotype.Selector;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

namespace SunnyPaine.Autofac.Extension.Mvvm.IOC
{
    /// <summary>
    /// 注入MVVM。
    /// </summary>
    public static class InjecterMvvm
    {
        /// <summary>
        /// 主窗口视图的类型。
        /// </summary>
        private static Type mainView = null;


        /// <summary>
        /// 启用MVVM扩展。
        /// </summary>
        /// <param name="builder">Autofac的IOC构建器。</param>
        public static void UseMvvm(this ContainerBuilder builder)
        {
            builder.RegisterType<ViewContext>().As<IViewContext>().SingleInstance();
        }

        /// <summary>
        /// 设置主窗口。
        /// </summary>
        /// <typeparam name="TWindow"></typeparam>
        /// <param name="builder"></param>
        public static void SetMainWindow<TWindow>(this ContainerBuilder builder)
        {
            InjecterMvvm.mainView = typeof(TWindow);
            builder.RegisterWindow<TWindow>(InjecterMvvm.mainView.Name);
        }

        /// <summary>
        /// 注册视图。
        /// </summary>
        /// <param name="builder"></param>
        public static void RegisterView(this ContainerBuilder builder)
        {
            List<string> files = new List<string>();
            Func<string, bool> func = (p) =>
            {
                FileInfo fi = new FileInfo(p);
                return !fi.Name.StartsWith("System")
                    && !fi.Name.StartsWith("Microsoft")
                    && !"SqlSugar.dll".Equals(fi.Name)
                    && !"Autofac.dll".Equals(fi.Name)
                    && !"Castle.Core.dll".Equals(fi.Name)
                    && (".exe".Equals(Path.GetExtension(p)) || ".dll".Equals(Path.GetExtension(p)));
            };
            IEnumerable<string> _files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory)
                                                  .Where(p => func(p));
            files.AddRange(_files);

            foreach (string file in files)
            {
                Assembly assembly = Assembly.LoadFile(file);
                Type[] types = assembly.GetTypes().Where(p => !p.IsInterface
                                                            && !p.IsAbstract
                                                            && p.IsPublic
                                                            && p != InjecterMvvm.mainView
                                                            && (typeof(IWindow).IsAssignableFrom(p) || typeof(IControl).IsAssignableFrom(p)))
                                                  .ToArray();
                foreach (Type type in types)
                {
                    var registrationBuilder = builder.RegisterType(type);
                    if (typeof(IWindow).IsAssignableFrom(type))//窗口视图
                    {
                        registrationBuilder.Named<IWindow>(type.Name).As<IWindow>()
                                           .PropertiesAutowired(new AutowiredPropertySelector())
                                           .PropertiesAutowired(new ResourcePropertySelector());
                    }
                    else if (typeof(IControl).IsAssignableFrom(type))//组件
                    {
                        registrationBuilder.Named<IControl>(type.Name).As<IControl>()
                                           .PropertiesAutowired(new AutowiredPropertySelector())
                                           .PropertiesAutowired(new ResourcePropertySelector());
                    }
                }
            }
        }

        /// <summary>
        /// 注册视图。
        /// </summary>
        /// <param name="builder">Autofac的IOC构建器。</param>
        /// <param name="viewName">视图名称。</param>
        /// <typeparam name="TWindow">视图实例类型。</typeparam>
        public static void RegisterWindow<TWindow>(this ContainerBuilder builder, string viewName)
        {
            builder.RegisterType<TWindow>().Named<IWindow>(viewName).As<IWindow>()
                   .PropertiesAutowired(new AutowiredPropertySelector())
                   .PropertiesAutowired(new ResourcePropertySelector());
        }

        /// <summary>
        /// 注册视图组件（例如用户控件、自定义控件等）。
        /// </summary>
        /// <param name="builder">Autofac的IOC构建器。</param>
        /// <param name="controlName">组件名称。</param>
        /// <typeparam name="TControl">组件的实例类型。</typeparam>
        public static void RegisterControl<TControl>(this ContainerBuilder builder, string controlName)
        {
            builder.RegisterType<TControl>().Named<IControl>(controlName).As<IControl>()
                .PropertiesAutowired(new AutowiredPropertySelector())
                .PropertiesAutowired(new ResourcePropertySelector());
        }

        /// <summary>
        /// 显示主窗口。
        /// </summary>
        /// <param name="container"></param>
        public static void ShowMainWindow(this IContainer container)
        {
            IViewContext viewContext = container.Resolve<IViewContext>();
            IWindow view = viewContext.Resolve(mainView.Name);
            view.Show();
        }
    }
}